home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AGA Toolkit '97
/
The AGA Toolkit '97.iso
/
c
/
du.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-07
|
8KB
|
289 lines
/********************************************************************\
* *
* Dave's DU version 1.01 *
* *
* ©1991 by Dave Schreiber. All rights reserved. This program may *
* be freely distributed. The only charges allowed in relation to *
* distributing this program is in relation to media, shipping, and *
* handling costs. *
* *
* Version list: *
* 1.02 (05/24/91) - Improved CTRL-C handling *
* 1.00 (04/29/91) - Original release version *
* *
* Compiled with SAS/C V5.10. To compile, do the following: *
* 1> lc DU *
* 1> blink with DU.lnk *
* *
\********************************************************************/
#include <exec/types.h>
#include <exec/exec.h>
#include <exec/tasks.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <stdio.h>
#include <signal.h>
ULONG *DOSBase;
/*Function prototypes*/
ULONG __regargs getDirSize(BPTR lock,char *dirName);
void interpretArgs(int argc,char *argv[],WORD *countDirs,WORD *countFiles,
char *dirName);
void printSize(char *dirName,ULONG size);
void printHelp(void);
void ctrlC_Handler(void);
/*-------------------*/
/*Pragmas*/
#pragma syscall AllocMem C6 1002
#pragma syscall FreeMem D2 0902
#pragma syscall FindTask 126 901
#pragma libcall DOSBase CurrentDir 7E 101
#pragma libcall DOSBase Examine 66 2102
#pragma libcall DOSBase ExNext 6C 2102
#pragma libcall DOSBase Lock 54 2102
#pragma libcall DOSBase UnLock 5A 101
/*-------*/
/*Global variables*/
WORD countFiles,countDirs;
struct Task *task;
BYTE quitNow=FALSE;
/*----------------*/
/*Defines*/
#define ERROR 0xFFFFFFFF
#define ABS(x) ((x) < 0 ? -(x) : (x))
/*-------*/
/*Main. Initializes, find the directory size, and then cleans up*/
main(int argc,char *argv[])
{
BPTR lock;
char dirName[256];
LONG totalSize;
/*Interpret the command line arguments*/
interpretArgs(argc,argv,&countDirs,&countFiles,dirName);
/*Replace the CTRL-C handler*/
signal(SIGINT,ctrlC_Handler);
/*Get a lock on the provided directory name*/
lock=Lock(dirName,SHARED_LOCK);
if(lock == NULL) /*Abort if the directory isn't there*/
{
fputs("Couldn't access the directory you requested; aborting.\n",
stderr);
exit(200);
}
/*Get the size of the contents of the directory*/
totalSize=getDirSize(lock,dirName);
/*Abort if something went wrong, otherwise print the directory size*/
if(totalSize == ERROR)
fputs("Error. Aborting!\n",stderr);
else
if(!countDirs && !quitNow)
printSize(dirName,totalSize);
UnLock(lock); /*Free the lock on the top directory*/
exit(0); /*And exit*/
}
/*Get the size of the contents of the specified directory (recursive)*/
ULONG __regargs getDirSize(BPTR lock,char *dirName)
{
register ULONG totalSize=0;
register struct FileInfoBlock *fib;
register BPTR dirLock,oldCurDir;
register UWORD dirNameLen;
register ULONG size;
dirNameLen=strlen(dirName);
/*Allocate (longword aligned) FileInfoBlock structure*/
fib=(struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),
MEMF_PUBLIC,MEMF_CLEAR);
if(fib==NULL)
return(ERROR);
/*Save the current directory, and change to the directory we need*/
/*to find the size of.*/
oldCurDir=CurrentDir(lock);
Examine(lock,fib);
/*For each file/directory, get the size...*/
while(ExNext(lock,fib) && !quitNow)
{
totalSize++; /*Add 1 (for the directory entry)*/
if(ABS(fib->fib_EntryType) != 4) /*If the file isn't a link...*/
{
if(fib->fib_EntryType < 0) /*If the file isn't a directory*/
{ /*get the size directly*/
/*Add the size to the total*/
totalSize+=fib->fib_NumBlocks;
if(countFiles) /*If the user wants the size of each file*/
{ /*printed, print the file size*/
if(dirNameLen!=0 && dirName[dirNameLen-1]!=':')
strcat(dirName,"/");
strcat(dirName,fib->fib_FileName);
printSize(dirName,totalSize);
dirName[dirNameLen]=NULL;
}
}
else /*It's a directory*/
{
/*Get the lock on the directory*/
dirLock = Lock(fib->fib_FileName,SHARED_LOCK);
if(dirLock == NULL) /*Abort if there was a problem getting*/
{ /*a lock on the directory*/
CurrentDir(oldCurDir);
fputs("Couldn't lock directory:",stderr);
fputs(fib->fib_FileName,stderr);
fputs("\n",stderr);
FreeMem(fib,sizeof(struct FileInfoBlock));
return(ERROR);
}
/*Create the full name of the directory we're going to */
/*descend into*/
if(dirNameLen!=0 && dirName[dirNameLen-1]!=':')
strcat(dirName,"/");
strcat(dirName,fib->fib_FileName);
/*Recursively get the directory size*/
size=getDirSize(dirLock,dirName)-1;
UnLock(dirLock);
if(size==ERROR) /*Abort if there was an error*/
{
CurrentDir(oldCurDir);
FreeMem(fib,sizeof(struct FileInfoBlock));
return(ERROR);
}
else
totalSize+=size+2; /*Otherwise, add the size to the total*/
/*Restore the old directory name*/
dirName[dirNameLen]=NULL;
}
}
}
CurrentDir(oldCurDir);
if(quitNow) /*If the user pressed CTRL-C, abort*/
fputs("*** Break: du\n",stderr);
else
if(countDirs) /*If CTRL-C wasn't pressed, print the size of the*/
printSize(dirName,totalSize); /*directory (if the user wants it)*/
/*Deallocate the FileInfoBlock*/
FreeMem(fib,sizeof(struct FileInfoBlock));
/*Return the total size*/
return(totalSize);
}
/*Interpret the command line arguments*/
void interpretArgs(int argc,char *argv[],WORD *countDirs,WORD *countFiles,
char *dirName)
{
int i;
if(argv[1][0]=='?') /*The user is asking for help*/
{
printHelp();
exit(0);
}
/*Set these variables to their default value*/
*countDirs=TRUE;
*countFiles=FALSE;
strcpy(dirName,"");
for(i=1;i<argc;i++)
{
if(argv[i][0]=='-')
switch(argv[i][1])
{
case 's': /*Don't print the size of each directory*/
case 'S':
*countDirs=FALSE;
break;
case 'a': /*Print the size of each directory*/
case 'A':
*countFiles=TRUE;
break;
}
else /*If the first character wasn't '-', the argument must be the*/
strcpy(dirName,argv[i]); /*directory name*/
}
/*If the user specified that directory sizes wouldn't be printed,*/
/*don't print out the file sizes either*/
if(*countDirs==FALSE)
*countFiles=FALSE;
return;
}
/*Make the directory/file name, then print out the size*/
void printSize(char *dirName,ULONG size)
{
char sizeStr[16];
/*Conver the size (int) to a string*/
stci_d(sizeStr,size);
/*Print it out*/
fputs(sizeStr,stdout);
/*Print out a TAB*/
fputs("\t",stdout);
/*Print out the directory name, or '.' if it's the current directory*/
if(dirName[0]==NULL)
puts(".");
else
puts(dirName);
/*Flush the output stream*/
flushall();
return;
}
/*Print help*/
void printHelp(void)
{
puts("\nDave's DU V1.01 ©1991 by Dave Schreiber. All rights reserved.");
puts("\nUsage:");
puts(" du [-s][-a][<dir>]");
puts("-s -- Print only the grand total size");
puts("-a -- Print the size for each file");
puts("<dir> -- Starting directory");
puts("");
return;
}
/*CTRL-C handler*/
void ctrlC_Handler(void)
{
signal(SIGINT,ctrlC_Handler);
quitNow=TRUE;
return;
}